package org.cashbook.utilities.logger;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Abstract logger class every logger should inherit from. Contains important methods for verifying correct writing of 
 * logging messages.
 * 
 * @author Jascha
 */
public abstract class AbstractLogger implements ILogger {
	protected String loggingLevel;
	protected SimpleDateFormat timeFormat;

	public AbstractLogger(String loggingLevel) {
		this.loggingLevel = loggingLevel;
		timeFormat = new SimpleDateFormat("dd.MM.yy H:mm:ss");
		info("--> [LOGGER] <-- // New session started // --> [LOGGER] <--", this);
	}
	
	/**
	 * Returns a boolean value which is used to check if method is allowed to write the current message into the log file or not.
	 * The method of the logger which is called for writing a message to the log file has to call this method with it's own method name
	 * to verify that it is allowed to write the current message to the log file.
	 * 
	 * @param method Method that wants to log an event
	 * @return Boolean if writing message to log file (or whatever target is used) or not
	 */
	protected boolean writeAllowed(String method) {
		if((method.equals(ILogger.FINEST) && loggingLevel.equals(ILogger.FINEST))
		|| (method.equals(ILogger.FINER) && (loggingLevel.equals(ILogger.FINER) || writeAllowed(ILogger.FINEST)))
		|| (method.equals(ILogger.FINE) && (loggingLevel.equals(ILogger.FINE) || writeAllowed(ILogger.FINER)))
		|| (method.equals(ILogger.CONFIG) && (loggingLevel.equals(ILogger.CONFIG) || writeAllowed(ILogger.FINE)))
		|| (method.equals(ILogger.INFO) && (loggingLevel.equals(ILogger.INFO) || writeAllowed(ILogger.FINE)))
		|| (method.equals(ILogger.WARNING) && (loggingLevel.equals(ILogger.WARNING) || writeAllowed(ILogger.INFO)))
		|| (method.equals(ILogger.SEVERE)))
			return true;
		else
			return false;
	}
	
	public void severe(String message, Object object) {
		if(writeAllowed(ILogger.SEVERE))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.SEVERE + "] " + message + " (In " + object.getClass() + ")");
	}

	public void warning(String message, Object object) {
		if(writeAllowed(ILogger.WARNING))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.WARNING + "] " + message + " (In " + object.getClass() + ")");
	}

	public void info(String message, Object object) {
		if(writeAllowed(ILogger.INFO))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.INFO + "] " + message + " (In " + object.getClass() + ")");
	}

	public void config(String message, Object object) {
		if(writeAllowed(ILogger.CONFIG))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.CONFIG + "] " + message + " (In " + object.getClass() + ")");
	}

	public void fine(String message, Object object) {
		if(writeAllowed(ILogger.FINE))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.FINE + "] " + message + " (In " + object.getClass() + ")");
	}

	public void finer(String message, Object object) {
		if(writeAllowed(ILogger.FINER))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.FINER + "] " + message + " (In " + object.getClass() + ")");
	}

	public void finest(String message, Object object) {
		if(writeAllowed(ILogger.FINEST))
			writeMessage("[" + getFormattedTime() + "] [" + ILogger.FINEST + "] " + message + " (In " + object.getClass() + ")");
	}
	
	/**
	 * Writes the specified message to specific output.
	 * 
	 * @param message Contains message to be written
	 */
	protected abstract void writeMessage(String message);
	
	/**
	 * Returns the current date as dd.MM.yy H:mm:ss.
	 */
	protected String getFormattedTime() {
		return (timeFormat.format(new Date()));
	}
}
